%
% Niniejszy plik stanowi przykład formatowania pracy magisterskiej na
% Wydziale MIM UW.  Szkielet użytych poleceń można wykorzystywać do
% woli, np. formatujac wlasna prace.
%
% Zawartosc merytoryczna stanowi oryginalnosiagniecie
% naukowosciowe Marcina Wolinskiego.  Wszelkie prawa zastrzeżone.
%
% Copyright (c) 2001 by Marcin Woliński <M.Wolinski@gust.org.pl>
% Poprawki spowodowane zmianami przepisów - Marcin Szczuka, 1.10.2004
% Poprawki spowodowane zmianami przepisow i ujednolicenie
% - Seweryn Karłowicz, 05.05.2006
% dodaj opcję [licencjacka] dla pracy licencjackiej
\documentclass[licencjacka]{pracamgr}

\usepackage{polski}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
%\usepackage{floatflt}

\DeclareGraphicsExtensions{.png}

\newcommand\makeimagewithlabel[4] %
{ %
  \begin{figure}[ht]
  \begin{center}
    \includegraphics[width=80mm,height=60mm]{images/#1}%
    \caption[#2]{#3}
    \label{fig:#4}
  \end{center}
  \end{figure}
} %

\newcommand\makeimagewithlabelnosize[4] %
{ %
  \begin{figure}[h]
  \begin{center}
    \includegraphics[width=110mm,height=15mm]{images/#1}%
    \caption[#2]{#3}
    \label{fig:#4}
  \end{center}
  \end{figure}
} %

\newcommand\makeimagewithlabellong[6] %
{ %
  \begin{figure}[ht]
    \includegraphics[width=#5mm,height=#6mm]{images/#1}%
    \caption[#2]{#3}
    \label{fig:#4}
  \end{figure}
} %

% Dane magistranta:

\author{Tomasz Bloch}

\nralbumu{171957}

\title{Klient sieci BitTorrent}

\tytulang{BitTorrent network client}

%kierunek: Matematyka, Informatyka, ...
\kierunek{Informatyka}

% informatyka - nie okreslamy zakresu (opcja zakomentowana)
% matematyka - zakres moze pozostac nieokreslony,
% a jesli ma byc okreslony dla pracy mgr,
% to przyjmuje jedna z~wartosci:
% {metod matematycznych w finansach}
% {metod matematycznych w ubezpieczeniach}
% {matematyki stosowanej}
% {nauczania matematyki}
% Dla pracy licencjackiej mamy natomiast
% mozliwosc wpisania takiej wartosci zakresu:
% {Jednoczesnych Studiow Ekonomiczno--Matematycznych}

% \zakres{Tu wpisac, jesli trzeba, jedna z~opcji podanych wyzej}

% Praca wykonana pod kierunkiem:
% (podać tytuł/stopień imię i nazwisko opiekuna
% Instytut
% ew. Wydział ew. Uczelnia (jeżeli nie MIM UW))
\opiekun{Krzysztofa Ciebiery}

% miesiąc i~rok:
\date{Wrzesień 2007}

%Podać dziedzinę wg klasyfikacji Socrates-Erasmus:
\dziedzina{
%11.0 Matematyka, Informatyka:\\
%11.1 Matematyka\\
%11.2 Statystyka\\
11.3 Informatyka\\
%11.4 Sztuczna inteligencja\\
%11.5 Nauki aktuarialne\\
%11.9 Inne nauki matematyczne i informatyczne
}

%Klasyfikacja tematyczna wedlug AMS (matematyka) lub ACM (informatyka)
%\klasyfikacja{...}

% Słowa kluczowe:
\keywords{sieć, BitTorrent, GTK+}

% Tu jest dobre miejsce na Twoje własne makra i~środowiska:
%\newtheorem{defi}{Definicja}[section]

% koniec definicji

\begin{document}
%\maketitle
\begin{titlepage}
    \begin{center}
      {\LARGE\textbf{Uniwersytet Warszawski}\\
        Wydział Matematyki, Informatyki i Mechaniki\\
        Zawodowe studia informatyki\par}
      \vspace{2cm}
      {\Large\bf{Tomasz Bloch}\par}
      \vspace{0.2cm}
      {\large Nr albumu: 171957\par}
      \vspace{0.2cm}
      {\Large\bf{Tomasz Socha}\par}
      \vspace{0.2cm}
      {\large Nr albumu: 532\par}
      \vspace{2cm}
      {\Huge\bf{Klient sieci BitTorrent }\par}
      {\large Praca licencjacka\par}
      {\large na kierunku INFORMATYKA\par}
      \vspace{2cm plus 1fill}
      \begin{flushright}\large
        \begin{tabular}{l}
          Praca wykonana pod kierunkiem\\ %
          \textbf{Krzysztofa Ciebiery}
        \end{tabular}
      \end{flushright}
      \vspace{2cm plus 1fill}
      {\large wrzesień 2007\par}
    \end{center}
\end{titlepage}
\begin{titlepage}
    %\large
    %\null
    %\vfill

   \textbf{\Large Oświadczenie kierującego pracą}
      \vspace{10mm}

   Potwierdzam, że niniejsza praca została przygotowana pod~moim
   kierunkiem i~kwalifikuje się do przedstawienia jej w~postępowaniu
   o~nadanie tytułu zawodowego.
   \vspace{15mm}

   Data \hfill Podpis kierującego pracą

   \vspace{3cm}
   \textbf{\Large Oświadczenie autora (autorów) pracy}
    \vspace{10mm}

   Świadom odpowiedzialności prawnej oświadczam, że niniejsza praca dyplomowa została
   napisana przeze mnie samodzielnie i~nie zawiera treści uzyskanych w sposób niezgodny
   z~obowiązującymi przepisami.

   Oświadczam również, że przedstawiona praca nie była
   wcześniej przedmiotem procedur związanych z uzyskaniem tytułu zawodowego w wyższej uczelni.

   Oświadczam ponadto, że niniejsza wersja pracy jest identyczna z~załączoną wersją elektroniczną.
   \vspace{15mm}

   Data \hfill Podpis autora (autorów) pracy
    \vspace{4cm}
  \end{titlepage}
%tu idzie streszczenie na strone poczatkowa
\begin{abstract}
  W~pracy przedstawiono protokół komunikacji w~sieci BitTorrent, a także implementację klienta takiej sieci.
\end{abstract}

\tableofcontents
%\listoffigures
%\listoftables

\chapter*{Wprowadzenie}
\addcontentsline{toc}{chapter}{Wprowadzenie}

BitTorrent to protokół wymiany i dystrybucji plików przez Internet.
Zarówno pobieranie i~wysyłanie jest realizowane w~ten sam sposób --- za~pomocą klienta sieci BitTorrent. Dodatkowym
elementem systemu jest serwer śledzący (ang. {\em tracker}) nazywany dalej serwerem, który służy do~wymiany informacji o~użytkownikach zainteresowanych danym
plikiem, a także niewielki plik  zawierający metadane (m.in. na~temat serwera oraz udostępnianych plików) upubliczniony za~pomocą tradycyjnych metod np. strony WWW, list dyskusyjnych, itp.

Integralną częścią tej pracy jest aplikacja obsługująca pobieranie i~wysyłanie plików
za~pomocą protokołu BitTorrent. Program został napisany w~języku C i~C++ przy wykorzystaniu
bibliotek libtorrent oraz GTK+.


W pierwszym rozdziale zamieszczone zostały objaśnienia skrótów i terminów używanych w dalszej części pracy.
Drugi rozdział zawiera pełne tłumaczenie opisu protokołu BitTorrent. W kolejnym rozdziale przedstawiona jest
dokumentacja użytkowa programu który jest przedmiotem niniejszej pracy. Ostatni rozdział jest opisem
implementacji programu.

\chapter{Objaśnienie skrótów i~terminów}\label{r:terminy}

\section{Pojęcia związane z~protokołem BitTorrent}

Wszystkie terminy pochodzą z~języka angielskiego. Jak dotąd nie przyjęło~się ich polskie tłumaczenie.
\begin{itemize}
\item[] \textbf{\emph{torrent}} - dane do udostępnienia/pobrania
\item[] \textbf{\emph{peer}} - użytkownik, który bierze udział w~pobieraniu danego pliku --- pobiera i/lub wysyła dane
\item[] \textbf{\emph{seed}} - \emph{peer}, który posiada kompletne pliki i~je udostępnia
\item[] \textbf{\emph{leecher}} - \emph{peer}, który nie posiada kompletnych plików
\item[] \textbf{\emph{swarm}} - zbiór wszystkich \emph{peerów} związanych z~danym \emph{torrentem}
\item[] \textbf{\emph{tracker}} - serwer śledzący przekazujący adresy IP użytkowników pobierających i~wysyłających pliki oraz~dodatkowe informacje statystyczne
\item[] \textbf{\emph{metafile}} - plik zawierający podstawowe informacje niezbędne do pobierania danych za~pomocą sieci BitTorrent
(adres serwera, nazwy i~rozmiary plików itp.); zwykle z~rozszerzeniem .torrent
\item[] \textbf{\emph{bencoding}} - sposób kodowania metadanych używany w~plikach \emph{.torrent} oraz w~komunikacji
z serwerem
\item[] \textbf{\emph{piece}} - część danych składających~się na~\emph{torrent}; w~pliku \emph{.torrent} znajdują się
policzone wartości funkcji \emph{SHA1} dla każdej części
\item[] \textbf{\emph{block}} - porcja danych transmitowana pomiędzy klientami
\end{itemize}

\section{Inne terminy}
\begin{itemize}
\item[] \textbf{GTK+} -- biblioteka służąca do tworzenia interfejsów użytkownika dla programów komputerowych
\item[] \textbf{libtorrent} -- biblioteka implementująca protokół BitTorrent napisana przez Arvida Norberga\footnote{istnieje
również inna biblioteka o tej samej nazwie} i~publicznie dostępna na~licencji BSD
\end{itemize}

\chapter{Opis protokołu BitTorrent}\label{r:protokol}

\section{\emph{Bencoding}}

Na potrzeby protokołu BitTorrent wykorzystuje~się specjalne kodowania wykorzystywane do~komunikacji z~serwerem oraz zapisywania metadanych w~plikach \emph{.torrent}.
Możliwe jest zapisanie następujących typów danych:
\begin{itemize}
\item \textbf{łańcuch bajtów\footnote{najczęściej jest to po prostu łańcuch znaków czyli napis ale można w~ten sposób zapisywać też wartości binarne} (ang. \emph{string})} --- \texttt{<liczba>:<łańcuch>}\\
\texttt{<liczba>} oznacza długość łańcucha zapisaną w~ASCII jako liczba dziesiętna.\\
Przykłady:
  \begin{itemize}
  \item 4:pies
  \item 3:kot
  \end{itemize}
\item \textbf{liczba całkowita (ang. \emph{integer})} --- \texttt{i<liczba>e}\\
Liczba zapisana jest zapisana jako tekst ASCII w~formie dziesiętnej i~może być ujemna.
Zakres liczby nie jest określony ale przyjęło się, że jest to co najmniej liczba 64-bitowa
za znakiem (na potrzeby przesyłania dużych plików).\\
Przykład:
\begin{itemize}
\item \texttt{i-4e}
\item \texttt{i0e}
\item \texttt{i05e} --- niepoprawne, wiodące zera nie są dozwolone
\end{itemize}
\item \textbf{lista (ang. \emph{list})} --- \texttt{l<wartość\_0>...<wartość\_N>e}\\
Ciąg wartości poprzedzony literą \texttt{l}, po którym następuje litera \texttt{e}\\
Przykład:
\begin{itemize}
\item \texttt{l3:kot4:piesi5eli4e5:krowaee} --- lista, której elementami są napisy ,,kot'', ,,pies'', liczba 5,
oraz lista złożona z~liczby 4 i~napisu ,,krowa''
\end{itemize}
\item \textbf{słownik (ang. \emph{dictionary})} --- \texttt{d<klucz\_0><wartość\_0>...<klucz\_N><wartość\_N>e}\\
Ciąg par (klucz, wartość) poprzedzony literą \texttt{d} a zakończony literą \texttt{e}. Kluczami są łańcuchy znaków,
natomiast wartościami dowolne elementy.\\
Przykład:
\begin{itemize}
\item \texttt{d3:kot4miau4:pies3:haue} --- słownik, którego kluczami są napisy ,,kot'' i~,,pies'', a~wartościami napisy
,,miau'' oraz ,,hau''
\end{itemize}
\end{itemize}

\section{Organizacja danych}

Na potrzeby przesyłania dane są podzielone na~wiele fragmentów (ang. \emph{piece}).
Dla każdej części policzona jest funkcja skrótu SHA1 i~zapisana w~pliku \emph{torrent},
tak aby po pobraniu można było zweryfikować jej poprawność.

Dane, które składają~się z~wielu plików traktowane są jak jeden ciąg bajtów, w~którym pliki ustawione są
jeden z~drugim bez przerw. Granice części, na~które podzielone są dane nie muszą~się pokrywać z~granicami plików.

\section{Plik z~metadanymi}

W pliku znajduje~się \emph{bencodowany} słownik. Wszystkie napisy są zapisane z~użyciem kodowania UTF8.
Słownik zawiera następujące klucze:
\begin{itemize}
\item \textbf{info} --- słownik opisujący plik lub pliki. Są dwie możliwe formy: dla jedno- i~wieloplikowych torrentów.
Zawiera klucze:
\begin{itemize}
\item \textbf{piece length} --- rozmiar części (\emph{piece}) w~bajtach (liczba całkowita)
\item \textbf{pieces} --- łańcuch znaków składający~się ze skonkatenowanych wartości SHA1 dla kolejnych części;
jego długość to 20 x liczba części
\item (opcjonalnie) \textbf{private} --- liczba całkowita, która oznacza czy dozwolone jest pozyskiwanie źródeł w
inny sposób niż od \emph{trackera} (np. DHT czy PEX). Nie jest to część oficjalnej specyfikacji ale jest stosowana
w praktyce przez wiele klientów. Wartość 0 oznacza, że korzystanie z~innych źródeł jest dozwolone natomiast wartość 1
mówi, że należy korzystać jedynie z~serwera.

\item W przypadku gdy torrent składa~się jedynie z~jednego pliku dodatkowe pola to:
\begin{itemize}
\item \textbf{name} --- sugerowana nazwa pliku (łańcuch znaków)
\item \textbf{length} --- rozmiar pliku (liczba całkowita)
\item (opcjonalnie) \textbf{md5sum} --- łańcuch znaków o długości 32 bajtów oznaczający wartość funkcji skrótu MD5.
Nie jest używana w~protokole BitTorrent ale niektóre programy stosują tę wartość jako dodatkową weryfikację.
\end{itemize}

\item Dla torrentów wieloplikowych:
\begin{itemize}
\item \textbf{name} --- sugerowana nazwa katalogu głównego (łańcuch znaków)
\item \textbf{files} --- lista zawierająca słowniki, z~których każdy opisuje jeden plik i~zawiera klucze:
\begin{itemize}
\item \textbf{length} --- rozmiar pliku w~bajtach (liczba całkowita)
\item \textbf{path} --- lista reprezentująca ścieżkę (względem głównego katalogu podanego jako nazwę (ang. \emph{name}))
i nazwę pliku. Elementu listy są kolejnymi elementami ścieżki (bez separatora, który jest zależny od systemu),
a ostatni z~nich to nazwa pliku.
\item (opcjonalnie) \textbf{md5sum} --- łańcuch znaków o długości 32 bajtów oznaczający wartość funkcji skrótu MD5.
Niektóre programy stosują tę wartość jako dodatkową weryfikację poprawności danych.
\end{itemize}
\end{itemize}
\end{itemize}
\item \textbf{announce} --- URL serwera w~postaci łańcucha znaków
\item (opcjonalnie) \textbf{announce-list} --- ,,zapasowe'' serwery. W przypadku programów, które obsługują połączenia do wielu serwerów jednocześnie to pole jest wykorzystywane zamiast pola \emph{announce} (które jest ignorowane). Wartością jest lista, na~której pierwsza wartość to lista serwerów, do których należy podłączyć~się w~pierwszej kolejności; gdyby~się nie udało należy użyć serwerów z~następnej listy itd.
Przy następnej próbie komunikacji z~serwerem należy powtórzyć całą operację --- rozpocząć znów od pierwszej listy
\item (opcjonalnie) \textbf{creation date} --- liczba całkowita oznaczająca czas utworzenia jako
liczbę sekund od początku roku 1970 wg czasu UTC (standardowy Uniksowy format \emph{epoch}).
\item (opcjonalnie) \textbf{comment} --- komentarz autora (łańcuch znaków)
\item (opcjonalnie) \textbf{created by} --- nazwa i~wersja programu, za~pomocą którego utworzono plik torrent (łańcuch znaków)
\end{itemize}


\section{Komunikacja z~serwerem}

Serwer jest usługą HTTP/HTTPS, która odpowiada na~żądania HTTP GET. Żądanie ma standardową postać używaną
w skryptach CGI: URL serwera, po którym następuje znak zapytania(\texttt{?}), a następnie szereg parametrów w~postaci
\texttt{parametr=wartość} rozdzielonych średnikiem(\texttt{;}). Znaki spoza \texttt{0-9}, \texttt{a-z}, \texttt{A-Z},
oraz \texttt{\$-\_.+!*'()} muszą być cytowane za~pomocą \texttt{\%nn}, gdzie \texttt{nn} to heksadecymalna wartość
znaku (więcej w~RFC1738).
W odpowiedzi serwer odsyła dokument typu \emph{text/plain} zawierający dane zakodowane poprzez \emph{bencoding}.

\subsection{Żądania}

Parametrami żądania mogą być:
\begin{itemize}
\item \textbf{info\_hash} --- 20-znakowa wartość SHA1 policzona dla słownika \emph{info} z~piku zawierającego metadane
\item \textbf{peer\_id} --- 20-bajtowy łańcuch będący identyfikatorem klienta; generowany przez niego. Mozę być dowolnym
ciągiem znaków\footnote{Różne programy używają własnych konwencji. Wydaje się, że najczęściej spotykany jest zapis
wprowadzony przez program Azureus: myślnik, dwa znaki alfanumeryczne identyfikujące program, 4-cyfrowy numer wersji,
myślnik, losowy numer (np. -AZ2060-123456789012)}.
\item \textbf{port} --- numer portu zwykle z~przedziału 6881-6889
\item \textbf{uploaded},\textbf{downloaded} --- rozmiar wysłanych do/pobranych od innych klientów danych od momentu
wysłania zdarzenia \emph{started} (chociaż nie jest to oficjalnie zapisane w~specyfikacji przyjęło się, że obejmuje
również metadane)
\item \textbf{left} --- określa ile bajtów danych pozostało klientowi do pobrania
\item \textbf{compact} --- wskazuje, że klient akceptuje odpowiedzi w~trybie \emph{compact}; W tym trybie \emph{peer list}
jest zastąpione przez łańcuch zawierający po 6 bajtów na~jednego \emph{peera} (4 bajty - adres IP + 2 bajty port)
\item \textbf{no\_peer\_id} --- wskazuje, że serwer może pominąć \emph{peer\_id} w~odpowiedziach
\item \textbf{event} --- jeśli podane musi być jednym z:
\begin{itemize}
\item \textbf{started} --- pierwsze żądanie wysłane do serwera musi zawierać tę wartość
\item \textbf{stopped} --- wysyłane w~przypadku gdy klient zakończył działanie.
\item \textbf{completed} --- wysyłane gdy zakończono pobieranie, chyba że klient miał już 100\%
danych w~chwili podłączenia; na~potrzeby uaktualnienia statystyk serwera.
\end{itemize}
\item (opcjonalne) \textbf{ip} --- Zewnętrzny adres IP klienta. Z reguły nie jest wymagane ---
przyjmuje się, że adres klienta jest adresem, spod którego przyszło żądanie --- jednak zdarzają
się wypadki, kiedy podanie go jest konieczne (na~przykład kiedy klient i~serwer są w~tej samej sieci lokalnej).
\item (opcjonalne) \textbf{numwant} --- Liczba adresów jakie klient chciałby otrzymać.
\item (opcjonalne) \textbf{key} --- Dodatkowy klucz identyfikujący klienta. Nie jest przekazywany innym.
W założeniu ma identyfikować klienta w~przypadku gdy zmieniło~się jego IP.
\item (opcjonalne) \textbf{trackerid} --- jeśli poprzednie rozgłoszenie zawierało \emph{trackerid} powinno się
ono znaleźć tutaj
\end{itemize}

\subsection{Odpowiedzi}

Odpowiedzią na~żądanie jest dokument \emph{text/plain} z~\emph{bencodowanym} słownikiem o następujących kluczach:

\begin{itemize}
\item \textbf{failure reason} --- jeśli został podany może być jedynym kluczem. Wartością jest łańcuch z~opisem błędu
w formie zrozumialej dla człowieka.
\item (opcjonalnie) \textbf{warning message} --- podobnie jak powyżej, jednak odpowiedź może być normalnie przetwarzana
\item \textbf{interval} --- co ile sekund klient powinien wysyłać żądania (liczba całkowita)
\item (opcjonalnie) \textbf{min interval} --- klient nie powinien wysyłać żądań częściej niż podana liczba sekund
\item (opcjonalnie) \textbf{tracker id} --- jeśli został podany klient powinien używać tego parametru w~kolejnych żądaniach
\item \textbf{complete}, \textbf{incomplete} --- liczba całkowita mówiąca o tym ilu jest podłączonych klientów mających
kompletne/niekompletne dane
\item \textbf{peers} (model słownikowy) --- lista słowników, z~których każdy zawiera klucze:
\begin{itemize}
\item \textbf{peer id} --- identyfikator klienta jaki przekazał (patrz wyżej)
\item \textbf{ip} --- łańcuch znaków zawierający adres IP (cztery liczby rozdzielone kropkami dla IPv4 lub postać
heksagonalna dla IPv6) bądź nazwę DNS
\item \textbf{port} --- liczba całkowita
\end{itemize}
\item \textbf{peers} (model binarny) --- łańcuch o długości będącej wielokrotnością liczby 6; pierwsze cztery bajty
z każdej szóstki oznaczają adres IP a pozostałe dwa numer portu
\end{itemize}

\subsection{Informacje statystyczne}

Niektóre serwery śledzące wspierają pobieranie informacji statystycznych. Jeśli w~URLu trackera bezpośrednio
po ostatnim znaku '/' występuje napis \emph{announce} można zastąpić go przez napis \emph{scrape}
i wysłać żądanie HTTP GET z~opcjonalnym parametrem \emph{info\_hash} (jak opisano powyżej).
W odpowiedzi serwer wyśle dokument \emph{text/plain} (opcjonalnie skompresowany programem gzip)
zawierający \emph{bencodowany} słownik zawierający klucze:
\begin{itemize}
\item \textbf{files} --- słownik składający~się z~kluczy \emph{info\_hash} i~wartości, którymi są słowniki z~kluczami:
\begin{itemize}
\item \textbf{complete} --- liczba klientów, którzy mają kompletne dane i~je udostępniają (\emph{seeds})
\item \textbf{incomplete} --- liczba klientów, którzy mają i~pobierają dane (\emph{leechers})
\item \textbf{downloaded} --- ile razy  zarejestrował zdarzenie \emph{complete}
\item (opcjonalnie) \textbf{name} --- nazwa \emph{torrenta}, jak podano w~słowniku \emph{info}
\end{itemize}
\item (nieoficjalne rozszerzenie) \textbf{failure reason} --- opis błędu
\item (nieoficjalne rozszerzenie) \textbf{flags} --- słownik; jednym z~kluczy może być:
\begin{itemize}
\item \textbf{min\_request\_interval} --- jak często można odpytywać o statystyki
\end{itemize}
\end{itemize}

\section{Komunikacja pomiędzy klientami}

Odbywa~się za~pomocą protokołu TCP/IP. Po pierwszej wiadomości (tzw. \emph{handshake}) klienci wymieniają pomiędzy sobą komunikaty utrzymując połączenie. Z każdym połączeniem związane są dwa stany (dla obu końców połączenia), który klient musi pamiętać:
\begin{itemize}
\item \textbf{choked} --- klient nie będzie wysyłał danych ani odpowiadał na~komunikaty dopóki nie zmieni stanu
\item \textbf{interested} --- klient jest zainteresowany pobieraniem części, które posiada druga strona
\end{itemize}

Klient może pobierać dane gdy jest w~stanie \emph{interested} i~druga strona nie jest w~stanie \emph{choked}.
Wysyłanie jest możliwe gry klient nie jest w~stanie \emph{choked} i~druga strona jest w~stanie \emph{interested}.
Dla klienta ważne jest aby na~bieżąco aktualizować stany wszystkich połączeń.

\subsection{\emph{handshake}}

Pierwszy komunikat wysłany przez klienta połączenie zawiera kolejno:
\begin{itemize}
\item \textbf{pstrlen} --- 1 bajt zawierający długość kolejnego pola \emph{pstr} (wersji 1.0 --- 19)
\item \textbf{pstr} --- napis identyfikujący protokół (wersji 1.0 jest to napis ,,BitTorrent protocol'')
\item \textbf{reserved} --- 8 bajtów zarezerwowanych na~potrzeby przyszłych zmian. W tej chwili we wszystkich
implementacjach wypełnione zerami
\item \textbf{info\_hash} --- 20 bajtów zawierające \emph{info hash} (opisane wcześniej)
\item \textbf{peer\_id} --- 20 bajtów z~identyfikatorem klienta (opisane wcześniej)
\end{itemize}

Jeśli klient otrzyma \emph{handshake} z~wartością \emph{info\_hash} nie pasujące do żadnego z~torrentów, które obecnie transmituje wtedy powinien zakończyć połączenie. W przeciwnym wypadku wysyła komunikat \emph{handshake} z~własnymi danymi.

Jeśli klient inicjujący połączenie otrzyma odpowiedź, w~której \emph{peer\_id} nie zgadza~się z~otrzymanym z~serwera\footnote{nie
musi znać tej wartości jeśli tracker wysłał listę klientów w~formie binarnej} powinien zakończyć połączenie.

\subsection{Komunikaty}

Po pomyślnym nawiązaniu połączenia klienci wymieniają komunikaty, które zawsze rozpoczynają~się 4-bajtową liczbą w~postaci
\emph{big-endian}, po których następuje identyfikator komunikatu (w postaci pojedynczego bajtu zawierającego znak od 0 do 9),
a następnie dane właściwe zależne od rodzaju komunikatu.

Typy komunikatów:
\begin{itemize}
\item \textbf{keep-alive}: $<\!len\!=\!0000\!>$

Komunikat \emph{keep-alive} jest komunikatem zerowym, w~którym początkowa
czterobajtowa liczba ustawiona jest na~zero. Nie posiada identyfikatora ani nie
zawiera żadnych innych danych, w~szczególności danych właściwych. Peer może zakończyć
połączenie jeżeli w~określonym przedziale czasowym (zazwyczaj 2 minuty) nie otrzyma żadnego komunikatu,
służy on więc dla podtrzymania uzgodnionego wcześniej połączenia.

\item \textbf{choke:} $<\!len\!=\!0001\!><\!id\!=\!0\!>$

Komunikat \emph{choke} jest ustalonej długości i~nie zawiera żadnych danych właściwych i~informuje o zaklinowaniu

\item \textbf{unchoke:} $<\!len\!=\!0001\!><\!id\!=\!1\!>$

Komunikat \emph{choke} jest ustalonej długości i~nie zawiera żadnych innych właściwych i~niesie ze sobą wiadomość o odklinowaniu klienta.

\item \textbf{intrested:} $<\!len\!=\!0001\!><\!id\!=\!2\!>$

Komunikat \emph{intrested} jest ustalonej długości i~nie zawiera żadnych innych właściwych i~informuje że klient jest zainteresowany pobieraniem danych.

\item \textbf{not intrested:} $<\!len\!=\!0001\!><\!id\!=\!3\!>$

Komunikat \emph{not intrested} jest ustalonej długości i~nie zawiera żadnych innych właściwych i~informuje że klient nie jest zainteresowany pobieraniem danych.

\item \textbf{have:} $<\!len\!=\!0005\!><\!id\!=\!4\!><\!piece$  $index\!>$

Komunikat jest ustalonej długości. Zaraz po identyfikatorze komunikatu znajduje~się index fragmentu (ang. \emph{piece}), którego pobieranie zostało właśnie zakończone i~zweryfikowane przez \emph{hash}. W rzeczywistości rozważne rozgłaszanie komunikatu może przyczynić~się do znacznego (nawet 50\% ) obniżenia ilości przesyłanych komunikatów typu \emph{have} a co za~tym idzie o~25-35\% redukcje komunikatów protokołu. Przez rozważne wysyłanie komunikatów rozumie~się tutaj np.: nie wysyłanie komunikatu \emph{have} do klientów, którzy posiadają rozpatrywany fragment.

\item \textbf{bitfield:} $<\!len\!=\!0001+X\!><\!id\!=\!5\!><\!bitfield\!>$

Jest to komunikat nieobowiązkowy. Wysyłany tylko i~wyłącznie gdy nawiązanie połączenia kończy~się sukcesem.
Długość komunikatu zależy bezpośrednio od wielkości pola bitowej znajdującej~się w~części danych właściwych komunikatu.
Wspomniane pole bitowe opisuje torrenta --- 0 dla kawałka brakującego i~1 dla kawałka już posiadanego. Koniec pola uzupełniony jest zerami. Klient powinien zerwać połączenie jeżeli pole bitowe jest nieprawidłowej długości tzn. jakikolwiek bit niezerowy po zadanej długości.

\item \textbf{request:} $<\!len\!=\!0013\!><\!id\!=\!6\!><\!index\!><\!begin\!><\!length\!>$

Komunikat o ustalonej długości. Używany jest do zgłaszania żądań o konkretny blok danych.
W części właściwej komunikatu przekazywane są następujące informacje:

\subitem \textbf{index:} indeks żądanego fragmentu

\subitem \textbf{begin:} dokładne miejsce w~wybranym fragmencie od którego to dane są potrzebne

\subitem \textbf{length:} długość żądanego fragmentu danych

\item \textbf{piece:} $<\!len\!=\!0009+X\!><\!id\!=\!6\!><\!index\!><\!begin\!><\!block\!>$

Komunikat o zmiennej długości, gdzie X jest długością bloku danych. Część właściwa komunikatu zawiera:

\subitem \textbf{index:} indeks żądanego fragmentu

\subitem \textbf{begin:} dokładne miejsce w~wybranym fragmencie od którego to dane są potrzebne

\subitem \textbf{block:} blok danych będący częścią fragmentu określonego przez \emph{index} i~\emph{begin}

Blok danych może być różnej wielkości. Obecnie przyjętym dla usprawnienia wydajności standardem jest $2^{16}$,
przy poprzednich wersjach było to $2^{32}$. Co nie znaczy wcale że klient proszący o dłuższy blok danych nie otrzyma go.

\item \textbf{cancel:} $<\!len\!=\!0013\!><\!id\!=\!8\!><\!index\!><\!begin\!><\!length\!>$

Komunikat o stałej długości zawierający w~części właściwej dane identyczne z~danymi wysyłanymi w~komunikacie \emph{request}.Służy
odwołania żądania bloku. Używany podczas fazy \emph{End Game}

\item \textbf{port:} $<\!len\!=\!0003\!><\!id\!=\!9\!><\!listen-port\!>$

Komunikat jest wykorzystywany przez nowszych klientów, w~których zaimplementowany jest \emph{DHT tracker}.
w części właściwej przekazywany jest numer portu, na~którym węzeł DHT klienta nasłuchuje.

\end{itemize}

\section{Algorytmy}\label{r:algorytmy}
Algorytmy BitTorrenta zostały zaprojektowane z~myślą o maksymalnym rozprzestrzenianiu~się pliku w~sieci,
a nie jak najszybszym przesłaniu go przez klienta udostępniającego.

\begin{itemize}
\item \textbf{\em Queuing}

Kolokowanie (ang. {\em Queuing}) jest stosowane do zwiększenia wydajności w~przesyłaniu pakietów. Klient
utrzymuje kilka żądań dla każdego połączenia żeby uniknąć ponownej pełnej wymiany komunikatów, po zakończeniu ściągania
jednego bloku danych z~fragmentu i~przystąpieniem do pobrania następnego bloku.Początkowo przyjmowaną głębokością
kolejki żądań było 5, lecz na~chwile obecna standardową głębokością jest 10. Kolejkowanie przestaje być tak znaczącą kwestią przy stale zwiększającymi~się przepustowościami używanych sieci, lecz jest to sprawa, która nie powinna być lekceważona

\item \textbf{\em Super Seeding}

Algorytm uprzywilejowanego udostępniania (ang. {\em Super Seeding}) sprzyja rozpowszechnianiu w~sieci
całości deklarowanego pliku, a polega na~tym, że klient udostępniający pozwala na~ponowne pobranie fragmentu
dopiero gdy zobaczy w~sieci jego kopie nie pochodzącą od niego samego. Głównym powodem takiego działania
jest próba wyważenia popularności fragmentów udostępnianego torrenta i~co za~tym idzie zwiększenie jego
dostępności przez wyeliminowanie rzadkich lub niewystępujących części.

Algorytm uprzywilejowanego udostępniania jest zazwyczaj stosowany przy pierwszym udostępnianiu torrenta.

\item \textbf{Strategie pobierania fragmentów}

Najefektywniejszą strategią pobierania fragmentów (ang. {\em  Piece downloading strategy}) jest strategia
polegająca na~pobieraniu w~pierwszej kolejności fragmentów dostępnych w~najmniejszej ilości kopii (ang. {\em rarest first}).
Najważniejszym powodem do obrania takiego działania jest zabezpieczenie~się przed stratą możliwości pobrania
takiego kawałka w~późniejszym czasie ( np.: w~przypadku gdy klienci udostępniający fragment zostaną odłączeni od sieci
lub co gorsza --- przestaną udostępniać torrenta).Drugą nie mniej ważna przyczyną jest oczywiście dążenie do idealnego układu,
gdy wszystkie fragmenty dostępne są w~takiej samej (dużej) liczbie kopii.

Inna strategią choć nie tak dobrą jest pobieranie losowych fragmentów torrenta co prowadzi również w~pewnym stopniu do
wyważenia dostępnych porcji danych jednakże dużo łatwiej może doprowadzić do wystąpienia sytuacji, że torrent jest niepełny
i nie zostanie nigdy pobrany w~całości.

\item \textbf{\em End Game}

Stosunkowo typowym zachowaniem jest spadek prędkości wraz ze zbliżającym~się zakończeniem pobierania pliku. Metodą
zapobiegającą takiemu jest rozsyłanie do wszystkich podłączonych klientów żądań o wszystkie brakujące fragmenty. Zwiększenie
wydajności jest także wspomagane wysyłaniem do wszystkich klientów komunikatu {\em cancel} po pobraniu kolejnej części.

Kwestią dyskusyjną pozostaje wciąż decyzja kiedy należy wejść do fazy kończącej (ang. {\em End Game)}. Niektóre rozwiązania
przyjmują ze do fazy końcowej należy wejść gdy zostały wysłane już żądania o wszystkie fragmenty.
Inne przystępują do ostatnie fazy gdy ilość bloków brakujących jest mniejszy niż ilość bloków właśnie
transmitowanych jak również liczba bloków transmitowanych nie przekracza 20.

\item \textbf{Klinowanie i~optymistyczne odklinowanie}

Klinowanie (ang. {\em chocking}) zostało zaimplementowanie z~paru powodów. Ruch TCP jest dalece nieefektywny gdy transmisja odbywa
się poprzez wiele połączeń, jak również pozwala klientom używać strategi wet-za-wet (ang. {\em tit-tor-tat}) w~celu zapewnienia,
sprawnego pobierania.

Algorytm opisany poniżej jest obecnie jedynym stosowanym. Ważne jest jednakże, aby wszystkie nowe algorytmy współdziałały
z~obecnie wykorzystywanym na~równi jak z~nimi samymi.

Jest kilka kryteriów, które powinien spełniać dobry algorytm klinujący. Powinien faworyzować równoległe wysyłanie dla zwiększenia wydajności TCP. Powinien unikać szybkiego klinowania i~odklinowywania zwanego także zatorem. Powinien odwzajemniać~się wysyłaniem klientom, od~których pobiera. A także powinien próbować nieużywanych połączeń, raz na~jakiś czas, aby sprawdzić czy nie będą one lepsze od obecnie wykorzystywanych --- znane jako optymistyczne odklinowanie (ang. {\em optimistic unchoking}.

Używany obecnie algorytm klinowania zapobiega zatorowi jedynie poprzez zmianę zaklinowanych klientów co kilka sekund.

Odklinowywanie czterech klientów, mających najlepsze współczynniki wysyłania, są zainteresowani dokonane zostaje na~podstawie
zasady odwzajemniania. Przez co zostaje zmaksymalizowany współczynnik pobierania klienta. Zostają oni zapamiętani jako {\em pobierający},
ponieważ są zainteresowani pobieraniem od klienta.

Klienci, którzy mają lepszy współczynnik wysyłania (w porównaniu do {\em pobierających}) lecz nie są zainteresowani zostają
również odklinowani. W momencie, gdy któryś z~nich wyrazi zainteresowanie zblokowany zostanie {\em pobierający} z~najniższym współczynnikiem wysyłania. W momencie zakończenia pobierania pliku klient częściej uwzględni współczynnik wysyłania
do wyznaczenia kolejnego klienta do odblokowania.

Do optymistycznego odklinowania, co określony czas wybierany jest klient bez względu na~jego współczynnik wysyłania (w przypadku gdy
takowy jest zainteresowany liczony on jest jako jeden z~czterech {\em pobierających}. Wybór klienta do optymistycznego odblokowania dokonuje~się co
30 sekund, a nowo podłączeni klienci mają trzykrotnie większą szanse na~wybór niż pozostali co daje im realną szanse na~pobranie
pełnego fragmentu, który mogą następnie wysyłać.

\item \textbf{\em Anty-snubbing}

Zdarzają~się sytuacje, że klient zostaje sklinowany przez wszystkich, od których formalnie pobiera. W takim przypadku pobieranie będzie
wstrzymane do czasu, aż optymistyczne odklinowywanie wybierze lepszych klientów. Jeżeli taka bezczynność trwa ponad minutę
klient przyjmuje że został zignorowany przez klientów i~wstrzymuje wysyłanie danych( nie wliczając w~to optymistycznego odklinowania).
W większości przypadków skutkuje to szybszym poprawieniem przesyłania niż ponowne nawiązywanie połączenia.

\end{itemize}

\section{Oficjalne rozszerzenia do protokołu}\label{r:oettp}

Obecnie jest kilka oficjalnych rozszerzeń do protokołu.

\begin{itemize}

\item \textbf{Fast Peers Extensions}

Rozszerzenia FPE (ang. {\em Fast Peers Extensions } mają wiele zastosowań. Pozwalają klientowi na~szybsze włączenie~się do społeczności poprzez danie puli fragmentów, które klient może pobrać pomijając klinowanie. Redukują narzut na~komunikaty protokołu poprzez dodanie komunikatów \textbf{HaveAll} i~\textbf{HaveNone}, a także udostępniają tak zwane jawne odrzucenie, podczas gdy w~standardowym protokole odrzucenie żądania o fragment nie było jawne i~mogło zakończyć~się zagłodzeniem klienta czekającego na~porcję danych, których by nigdy nie otrzymał.
\pagebreak

\item \textbf{Distributed Hash Table}

Rozszerzenie pozwala na~śledzenie klientów z~pominięciem standardowych serwerów.
Zaimplementowanie tablic haszujących (ang. {\em Distributed Hash Table --- DHT}) w~kliencie czyni go serwerem
przechowującym listy klientów i~węzłów, które mogą być wykorzystane do lokalizacji nowych  .
\item \textbf{Connection Encryption}

Rozszerzenie pozwana na~tworzenie szyfrowanych połączeń miedzy klientami, może być użyte do ominięcia {\em korków} w~sieci.

\end{itemize}

\chapter{Dokumentacja użytkowa}\label{r:uzyt}

Głównym założeniem przyjętym przy przystąpieniu do pracy nad klientem sieci BitTorrent, który jest
tematem niniejszej pracy, była przyjazność w~obsłudze dla każdego użytkownika. Przez przyjazność rozumiane
jest podejście, w~którym za~podstawowy cel obrano intuicyjną i~prostą obsługę programu. Prostą nie oznacza
w tym przypadku wcale braków w~funkcjonalności, a wręcz przeciwnie --- wyłuskane zostały najbardziej
przydatne i~najczęściej używane funkcje w~programach tego typu, a ukryte zostały opcje, z~których statystyczny
użytkownik nie korzysta lub nie wie jak wykorzystać dla poprawienia działania programu.\\
\makeimagewithlabel{tomtorent}{Główne okno programu}{Główne okno programu}{interface}
Program, którego zadaniem ma być pobieranie i~udostępnianie plików w~sieci BitTorrent powinien przede wszystkim
pozwalać użytkownikowi na~łatwe dodawanie (rysunek \ref{fig:dodawanie}) i~usuwanie (rysunek \ref{fig:usuwanie})
torrentów. Wszystkie funkcje potrzebne nam do obsługi zarówno pojedynczych jak i~wszystkich torrentów są dostępne
na trzy sposoby. Pierwszym najbardziej konserwatywnym jest tekstowe menu dostępne na~górnej listwie programu.
Drugą możliwość zarządzania torrentami daje nam menu obrazkowo-tekstowe (rysunek \ref{fig:picmenupl}) --- przejrzyste
i~duże ikony w~czytelny sposób obrazują swoją funkcję, a dla dociekliwych są podpisane. Trzecią możliwością zarządzania
jest menu kontekstowe, rozwijane po~kliknięciu prawym przyciskiem myszy na~wybranego torrenta. Oczom użytkownika ukazuje~się to samo menu, które znajduje~się na~górnej listwie poleceń w~menu {\em Torrent}.\\

\section{Lista torrentów}
Główne okno programu podzielone jest na~dwie części. Pierwsza z~nich, górna zawiera listę wszystkich
torrentów załadowanych do programu. Listę tę możemy dowolnie uporządkować.
\makeimagewithlabellong{listatorrentow}{Lista torrentów}{Lista torrentów}{lista}{160}{30}
\begin{itemize}
\item \textbf{\#} - liczba wskazująca miejsce w~kolejce torrentów. To właśnie wartości tej kolumny zmieniane są
poprzez użycie funkcji \em{w górę} \ref{wgore} i~\em{w dół} \ref{wdol}.
\item \textbf{Stan} - stan w~jakim jest torrent. Dostępne są trzy stany:
  \subitem - wstrzymany
  \subitem - pobierany
  \subitem - udostępniany
\item \textbf{Nazwa} - nazwa torrenta
\item \textbf{Rozmiar} - rozmiar torrenta
\item \textbf{Udostępniający} - ilość klientów udostępniających torrenta
\item \textbf{Pobierający} - ilość klientów pobierających klienta
\item \textbf{Pobieranie} - prędkość z~jaką torrent jest obecnie pobierany
\item \textbf{Wysyłanie} - prędkość z~jaką torrent jest obecnie wysyłany
\item \textbf{Postęp} - pasek postępu pobierania torrenta
\item \textbf{Ratio} - współczynnik {\em Ratio}
\end{itemize}

\section{Panel informacyjny}
Druga część okna głównego programu jest panelem informacyjnym zawierającym szczegółowe informacje
o wybranym obecnie torrencie. Informacje o torrent zostały podzielone na~cztery zakładki:
\begin{itemize}
\item \textbf{Informacje} - zakładka zawiera informacje o torrencie takie jak: data powstania,
    ilość i~rozmiar kawałków, informacje o twórcy, SHA torrenta czy komentarz do torrenta.
\item \textbf{Połączenia} - zakładka pokazuje stan połączeń, tzn. numery IP klientów,
rodzaje klientów jak i~prędkość transmisji danych.
\item \textbf{Części} - zakładka zawiera informacje o pobieranych aktualnie blokach danych
\item \textbf{Pliki} - zakładka pokazuje postęp w~pobieraniu poszczególnych plików torrenta jak również pozwala ustalić
priorytety względem, których ustalona zostanie kolejność pobierania plików.
\end{itemize}

\makeimagewithlabellong{infoPanel}{Panel informacyjny}{Panel informacyjny}{infopanel}{160}{60}

\section{Menu obrazkowo-tekstowe} \label{MenuOT}
Możliwość pełnego zarządzania torrentami możliwe jest przy użyciu menu obrazkowo-tekstowego
(rysunek \ref{fig:picmenupl}). Na~pasku dostępne są funkcje:
\makeimagewithlabelnosize{picturedmenupl}{Menu obrazkowo-tekstowe}{Menu obrazkowo-tekstowe}{picmenupl}
\begin{itemize}
\item \textbf{Dodaj} - dodawanie torrenta do listy obsługiwanych. Po wybraniu tej opcji pokazuje~się okno
wyboru torrenta do załadowania (rysunek \ref{fig:dodawanie}).
\makeimagewithlabel{dodawanietor}{Dodawanie torrenta do pobrania}{Dodawanie torrenta do pobrania}{dodawanie}
\item \textbf{Usuń} - usuwanie torrenta z~listy obsługiwanych. Po wybraniu tej opcji wyświetlone zostanie
potwierdzenie usunięcia torrenta (rysunek \ref{fig:usuwanie}).
\makeimagewithlabel{removetor}{Potwierdzenie usunięcia torrenta}{Potwierdzenie usunięcia torrenta}{usuwanie}
\item \textbf{Ustawienia} - wywołanie okna ustawień zaawansowanych. Po wybraniu opcji otwarte zostanie okno ustawień (rysunek \ref{fig:ustaw}) z~następującymi opcjami:
\begin{itemize}
\item \textbf{Nasłuchiwanie na~portach} - pozwala na~ustawienie zakresu portów, których klient będzie używał
\item \textbf{Liczba aktywnych torrentów} - ustalona zostaje liczba torrentów, które są ściągane w~tym samym czasie.
\item \textbf{Pobieraj do katalogu} - docelowy katalog, w~którym zapisywane są ściągnięte pliki
\item \textbf{Udostępniaj do} - parametr, który ustala jak długo torrent jest udostępniany do pobierania; liczba jest ilorazem bajtów wysłanych i~pobranych.
\item \textbf{Maksimum} - pierwsza liczba ustala maksymalną ilość połączeń, które może nawiązać klient, druga --- ustala maksymalną liczbę połączeń dla~wysyłania danych.
\item \textbf{Limit prędkości} - pozwala na~ograniczenie prędkości wysyłania i~pobierania torrentów w~Kb/s.
Wartość -1 ustawia brak limitów.
\item \textbf{Rozszerzenia} - pozwala na~włączenie/wyłączenie rozszerzeń protokołu PEX i~DHT.
\item \textbf{Zapisz ustawienia} - ustala co ile sekund są zapisywane ustawienia.
\end{itemize}
\item \textbf{W górę} \label{wgore} - przesunięcie torrenta w~górę na~liście torrentów
\item \textbf{W dół} \label{wdol} - przesunięcie torrenta w~dół na~liście torrentów
\item \textbf{Wyjście} - zapisanie stanu programu i~zakończenie jego działania
\end{itemize}
\pagebreak
\makeimagewithlabel{ustawienia_}{Okno ustawień}{Okno ustawień}{ustaw}

\chapter{Opis implementacji}\label{r:impl}

\section{Technologie} \label{technologie}

Przy tworzeniu programu został wykorzystany zestaw makr {\em Autoconf} (\ref{przenosnosc}) wspomagających przenośność programu,
a dzięki użyciu pakietu {\em gettext} (\ref{inter}) zapewniona została bezproblemowa internacjonalizacja oprogramowania.

\subsection{Przenośność}\label{przenosnosc}

GNU Autoconf to zestaw makr M4 stworzonych w~ramach projektu GNU,
służy do generowania skryptów powłoki, które mają zająć~się procesem  kompilacji programów komputerowych rozprowadzanych w~formie kodu źródłowego. Autoconf jest w~stanie dostosować się
do specyfiki wielu systemów operacyjnych bez angażowania użytkownika.

Podstawowym plikiem dla Autoconfa jest \verb!configure.in! lub \verb!configure.ac! (w zależności od wersji).
Na podstawie tego pliku program \verb!autoconf! generuje skrypt \verb!configure! w~katalogu głównym pakietu z~oprogramowaniem.
Skrypt ten, który jest uruchamiany przez użytkownika końcowego, sprawdza obecność programów, bibliotek i~spełnienia
innych warunków określonych przez programistę. W zależności od zastanej konfiguracji, Autoconf zmienia tworzone przez siebie pliki \verb!Makefile!, które to bezpośrednio odpowiadają za~kompilację programu. Następnie użytkownik, uzyskawszy już pliki \verb!Makefile!, wywołuje polecenie \verb!make!, aby skompilować program.

\subsection{Internacjonalizacja}\label{inter}

Gettext to pakiet oprogramowania, stworzony w~ramach projektu GNU, służący do internacjonalizacji programów komputerowych poprzez tłumaczenie ich komunikatów. W skład pakietu wchodzą narzędzia do tworzenia i~obróbki plików z~tłumaczeniami komunikatów (pliki .po) oraz funkcje biblioteczne m.in. dla języka C.

\subsection{Biblioteki GTK+}\label{gtk}

GTK+ to biblioteka służąca do tworzenia graficznych interfejsów użytkownika ({\em GUI}). Jest napisana w~języku C ale zaimplementowane są w niej struktury mają pewne cechy obiektowe oparte na systemie obiektów z biblioteki Glib --- m. in. dziedziczenie.
Podstawowym obiektem\footnote{chodzi tu o obiekty w sensie biblioteki Glib} jest \verb!GtkWidget!. \emph{Widget} jest to coś, co można wyświetlić na ekranie (np. okno, pole tekstowe, przycisk), albo pojemnik grupujący inne elementy.

Elementy interfejsu implementują system zdarzeń i sygnałów biblioteki Glib --- w~odpowiedzi na pewne zdarzenia ({\em event}) generowane są sygnały ({\em signal}), dla których programista może zdefiniować funkcje obsługi (\emph{callback}).
Na przykład dla \emph{widgetu} \verb!GtkButton!, (który implementuje przycisk) programista może zdefiniować funkcję obsługi sygnału \verb!clicked!, która zostanie wywołana w~odpowiedzi na zdarzenie kliknięcia przycisku.

\subsection{Biblioteka \emph{libtorrent}}

Biblioteka napisana przez Arvida Norberga implementuje protokół BitTorrent.
Interfejs biblioteki pozwala na~utworzenie sesji, dodanie do niej kilku torrentów, a następnie odpytywanie sesji oraz torrentów o stan pobierania, połączeń itp.

Pobieranie realizowane jest w~oddzielnym wątku, który powstaje w~chwili utworzenia sesji i~jest kończony w~momencie jej zamknięcia. Odpowiada on za~pobieranie i~wysyłanie danych dla wszystkich torrentów. Dodatkowy wątek jest też powoływany podczas dodawania torrenta i~odpowiada za~sprawdzenie poprawności danych (jeśli jakieś zostały już pobrane), a jeśli są prawidłowe torrent przekazywany jest do wątku sesji.

\section{Program Tom's Torrent}


\subsection{Głowna pętla}

W czasie działania programu tworzona jest sesja (\verb$libtorrent::session$) oraz okno zawierające widok listy torrentów (\verb$GtkTreeView$ z~modelem \verb$GtkListStore$), a także kilka dodatkowych widoków (w zakładkach), które pokazują szczegóły dla zaznaczonego na~głównej liście torrenta. Najważniejszą kolumną głównego modelu
(\verb$GtkListStore$) jest obiekt \verb$libtorrent::torrent_handle$ --- uchwyt torrenta dodanego do sesji. Poza tym pamiętane są tam wskaźniki do obiektów pokazywanych w~zakładkach (\verb$GtkListStore$ lub \verb$GtkTable$). Zawartość zakładek zmienia~się gdy zmieni~się zaznaczenie na~głównej liście (rejestrowany jest funkcja obsługi sygnału \verb$"changed"$ dla obiektu \verb$GtkTreeSelection$ związanego z~tą listą).

Za pomocą funkcji: \\
\hbox to \textwidth {\hfill \verb!g_timeout_add ( guint32 interval, GtkFunction function, gpointer data )!}
rejestrowana jest główna funkcja programu, która będzie wywoływana co \verb!interval! milisekund, a której zadaniem jest odświeżanie statystyk. Zarejestrowana funkcja:
\begin{itemize}
\item przegląda listę torrentów, odpytuje o status każdego z~nich (wywołując dla niego metodę \verb!torrent_handle::status()!) i~aktualizuje kolumny głównej listy
\item sprawdza status sesji (\verb$session::status()$) i~uaktualnia pasek statusu
\item uaktualnia zakładkę połączeń (wywołując, dla torrenta zaznaczonego na~głównej liście metodę \verb$torrent_handle::get_peers_info()$)
\item odświeża zakładkę pobieranych fragmentów (po wywołaniu  dla wybranego torrenta metody \verb$torrent_handle::get_download_queue()$).
\item co \verb$n$-te wywołanie zapisuje ustawienia (gdzie \verb!n! liczba ustawiana przez użytkownika)
\item zatrzymuje lub wznawia pobieranie/wysyłanie danych na~podstawie ustawień (liczba aktywnych torrentów, żądany stosunek wysłanych i~pobranych danych)
\end{itemize}
\noindent Aby nie obciążać niepotrzebnie procesora odświeżane są tylko statystyki pokazywane na~ekranie --- nieaktywne zakładki lub zminimalizowane okno nie są aktualizowane.

\subsection{Uruchomienie i~parametry startowe}

Parametry linii poleceń są parsowane za~pomocą mechanizmu dostarczanego przez bibliotekę Glib, a dokładniej obiektu \verb!GOptionContext!. Jeśli została podana opcja  \verb!--help! lub \verb!--version!, program wypisuje odpowiednio informacje pomocy lub informacje o wersji, a następnie kończy działanie. Pozostałe parametry traktowane są jak nazwa pliku z~metedanymi, torrenta, który należy dodać do sesji.

Jeśli jest już uruchomiona inna instancja programu nazwy plików są przekazywane poprzez gniazdo typu unix (ang \emph{unix socket}) do tamtej instancji, a następnie program kończy działanie.
W przypadku gdy uruchamiany program jest jedyną instancją --- tworzone jest gniazdo typu unix (na którym program będzie nasłuchiwał na~informacje od~później uruchomionych instancji), przywracana jest poprzednia sesja, następnie dodawane do~niej torrenty podane w~linii poleceń.

\subsection{Ustawienia i~dane sesji}

Program wykorzystuje podczas działania katalog \verb!$HOME/.torrent! do zapisywania danych o sesji (m.in. pobierane torrenty, ustawienia). Jeśli nie ma takiego katalogu to zostanie utworzony przy pierwszym uruchomieniu.

W pliku \verb!config!, są zapisywane i~odczytywane ustawienia sesji. Odbywa~się to za~pomocą obiektu \verb!GKeyFile! (z~biblioteki Glib). Format pliku jest zgodny z~tym interfejsem. Jest to plik tekstowy zawierający dane w~postaci \verb!klucz = wartość! podzielone na~kilka grup \verb![nazwa_grupy]!. Każda grupa zawiera dane dla jednego \emph{torrenta} (nazwa to wartość SHA1), z~wyjątkiem grupy \verb![SESSION]!, w~której są ustawienia globalne (dla sesji). Plik \verb!config! zapisywany jest cyklicznie (domyślnie co 5 min), aby zapobiec utracie informacji o~ilości wysłanych i~pobranych danych w~przypadku awarii.

W tym samym katalogu tworzony jest plik \verb!ttorrent-socket! --- plik powiązany z~połączeniem typu Unix opisanym wcześniej.

Dodatkowo, po dodaniu torrenta do pobierania, tworzony jest plik z~metadanymi, którego nazwa to SHA torrenta (bez rozszerzenia). W ten sposób na~podstawie danych zapisanych w~\verb!config! oraz w~metaplikach można odtworzyć sesję przy powtórnym uruchomieniu.

\chapter{Podsumowanie}

Powyższa praca stanowi kompletny opis protokołu BitTorrent oraz przykładowy program do obsługi tego protokołu,
Program Tom'sTorrent jest próbą stworzenia oprogramowania z~intuicyjnym interfejsem użytkownika w oparciu o najnowszą, dostępną, stabilną wersję protokołu, implementowaną przez bibliotekę libtorrent, z~wykorzystaniem najnowszych rozszerzeń
takich jak PEX i DHT. W założeniu ma być prosty, a jednocześnie funkcjonalny. Dodatkowo, pokazuje niektóre szczegóły, które mogą pomóc w zrozumieniu protokołu, jak np. połączenia wraz ze stanami, w jakich się znajdują czy kolejkę pobieranych fragmentów.

Program może być kompilowany i użytkowany na różnych systemach uniksowych, które obsługują bibliotekę GTK+ oraz gniazda typu unix.
Przygotowany został w~dwóch wersjach językowych, z możliwością dodania następnych wersji.
Możliwe jest również łatwe rozszerzenie o~nowe funkcjonalności.

%\appendix

%\chapter{Główna pętla programu zapisana w~języku T\=oFoo}

%\chapter{Przykładowe dane wejściowe algorytmu}

%\chapter{Przykładowe wyniki blabalizy
%    (ze~współczynnikami~$\sigma$-$\rho$)}


%\begin{thebibliography}{9}
%\addcontentsline{toc}{chapter}{Bibliografia}
%\end{thebibliography}

\end{document}


%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% coding: latin-2
%%% End:
